#!/usr/bin/python2.5
# -*- coding: utf-8 -*-
# Copyright (c) 2008 Christoph Heer (Christoph.Heer@googlemail.com)
# 
# Permission is hereby granted, free of charge, to any person obtaining a 
# copy of this software and associated documentation files (the \"Software\"), 
# to deal in the Software without restriction, including without limitation 
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the 
# Software is furnished to do so, subject to the following conditions: 
# 
# The above copyright notice and this permission notice shall be included in 
# all copies or substantial portions of the Software. 
# 
# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
# DEALINGS IN THE SOFTWARE. 

import telnetlib
import re

class TCPQuery(object):
    """This class can open a link to a Teamspeak2 Server and use its telnet functions. The functions
    have the same Name how its telnet function. The class have any special functions this functions have a X as the frist leatter."""    
    def __init__(self, ip='127.0.0.1', query=51234):
       self.IP = ip
       self.Query = int(query)
       self.Status = ()
       self.SelectedServer = 0
       self.IsLogin = False
       self.LoginType = None
       self.Timeout = 5.0
    def xconnect(self):
        """This function open a link to the teamspeak server."""
        try:
            self.telnet = telnetlib.Telnet(self.IP, self.Query)
        except telnetlib.socket.error:
            return ('ERROR', 60, 'Can not open a link on the port or IP')
        output = self.telnet.read_until('[TS]', self.Timeout)
        if output.endswith('[TS]') == False:
            return ('ERROR', 70, 'This is not a Teamspeak Server')
        else:
            self.xstatus()
            return ('OK', 100, '')     
    def xdisconnect(self):
        """This function close a open link to a teamspeak server."""
        if self.xstatus:
            self.telnet.write('quit \n')
            self.telnet.close()
            return ('Teamspeak', 100, 'Link now closed')
        else:
            return self.Status
    def xerror(self, data):
        data = re.split("\\n", data)
        msg = ('OK/ERROR', 50, 'ServerMessage can not decrypted')
        errorindex = {'invalid id':210, 'no server selected':220, 'invalid login':230, 'not logged in':240,
                      'no data available':250,'invalid paramcount':260,'server is running':270,'port already in use':280,
                      'invalid permissions':290,'Allready member of channel':300}
        _filterOK = re.compile(r'OK')
        _filterERROR = re.compile('ERROR, (.*?)\\r')
        for _line in data:
            _filterDataOK = _filterOK.match(_line)
            _filterDataERROR = _filterERROR.match(_line)
            if _filterDataOK != None:
                msg = ('0K', 100, '')
            elif _filterDataERROR != None:
                errormsg = str(_filterDataERROR.group(1))
                errorint = errorindex[errormsg]
                msg = ('ERROR', errorint, errormsg)  
        return msg
    def xstatus(self):
        sock = self.telnet.sock
        if sock == 0:
            self.Status = ('ERROR', 80, 'Link is not open')
            return False
        else:
            self.Status = ('OK', 100, '')
            return True
    def sl(self):
        """sl will return a list of ports on which there are virtual server instances running."""
        if self.xstatus:
            self.telnet.write("sl \n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = _data.split("\n")
                del _data[0]
                del _data[len(_data) - 1]
                data = []
                for i in _data:
                    data.append(int(i))
                return data
            else:
                return _msg
        else:
            return self.Status
    def sel(self, port):
        """Chooses the server specified with <serverport>, important for many following commands, that manipulate the selected server."""
        if self.xstatus():
            self.telnet.write("sel " + str(port) + " \n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            return _msg
            if _msg[1] == 100:
                self.SelectedServer = int(port)
                return _msg
            else:
                return _msg
        else:
            return self.Status 
    def login(self, username, password):
        """login will log a regular TS account. What you will be able to do depends on the permission settings... Logging in is necessary for all advanced commands. If you want to log in as superadmin (-> slogin)."""
        if self.xstatus():
            self.telnet.write("login " + str(username) + " " + password + " \n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                self.IsLogin = True
                self.LoginType = 'Login'
                return _msg
            else:
                return _msg
        else:
            return self.Status
    def slogin(self, username, password):
        """slogin will log into your superadmin account. This gives you all permissions possible - be careful with your commands :)."""
        if self.xstatus():
            self.telnet.write("slogin " + str(username) + " " + password + " \n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                self.IsLogin = True
                self.LoginType = 'SLogin'
                return _msg
            else:
                return _msg
        else:
            return self.Status
    def pl(self, port=0):
        """pl will return a lists of all users connected to the virtual server"""
        if port == 0:
            port = self.SelectedServer
        if self.xstatus():
            self.telnet.write("pl " + str(port) + "\n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _players = []
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s"(\d{1,}.\d{1,}.\d{1,}.\d{1,})"\s"(\S*)"\s"(\S*)"\s')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _player = [int(_filterdata.group(1)), int(_filterdata.group(2)), int(_filterdata.group(3)), int(_filterdata.group(4)), int(_filterdata.group(5)), int(_filterdata.group(6)), int(_filterdata.group(7)), int(_filterdata.group(8)), int(_filterdata.group(9)), int(_filterdata.group(10)), int(_filterdata.group(11)), int(_filterdata.group(12)), int(_filterdata.group(13)), str(_filterdata.group(14)), str(_filterdata.group(15)), str(_filterdata.group(16))]
                        _players.append(_player)
                return _players
            else:
                return _msg
        else:
            return self.Status
    def cl(self, port=0):
        """pl will return a lists of all users connected to the virtual server"""
        if port == 0:
            port = self.SelectedServer
        if self.xstatus():
            __players = []
            self.telnet.write("cl " + str(port) + "\n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _channels = []
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\d{1,})\s(\d{1,})\s(.*?)\s(\d{1,})\s(\d{1,})\s"(\S*)"\s(\d{1,})\s(\d{1,})\s"(\S*)"\s')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _channel = [int(_filterdata.group(1)), int(_filterdata.group(2)), int(_filterdata.group(3)), int(_filterdata.group(4)), int(_filterdata.group(5)), str(_filterdata.group(6)), int(_filterdata.group(7)), int(_filterdata.group(8)), str(_filterdata.group(9))]
                        _channels.append(_channel)
                return _channels
            else:
                return _msg
        else:
            return self.Status
    def ver(self):
        """ver return a list of versions infomation"""
        if self.xstatus():
            _version = []
            self.telnet.write('ver \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\d*.\d*.\d*.\d*)\s(\S*)\s(\S*)')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _version = [str(_filterdata.group(1)), str(_filterdata.group(2)), str(_filterdata.group(3))]
                return _version
            else:
                return _msg
        else:
            return self.Status
    def gi(self):       
        """gi will list lots of general (read: non virtual server specific) information."""
        if self.xstatus():
            _gi = {}
            self.telnet.write('gi \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\S*)=(.*?)\s')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _gi[_filterdata.group(1)] = _filterdata.group(2)
                return _gi
            else:
                return _msg
        else:
            return self.Status
    def si(self, port=0):       
        """gi will list lots of general (read: non virtual server specific) information."""
        if port == 0:
            port = self.SelectedServer
        if self.xstatus():
            _si = {}
            self.telnet.write('si %s \n' % (str(port)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filter = re.compile('(\S*)=(.*?)\\r')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _si[_filterdata.group(1)] = _filterdata.group(2)
                return _si
            else:
                return _msg
        else:
            return self.Status
    def msg(self, text):
        """Sends the text as a text message to all users connected to the currently selected (-> sel) server instance."""
        if self.xstatus():
            _msg = []
            self.telnet.write('msg @%s \n' % (str(text)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                return _msg
        else:
            return self.Status
    def msgu(self, playerid, text):
        """This is used to send a textmessage to a certain user that is currently connected to your server."""
        if self.xstatus():
            _msg = []
            self.telnet.write('msgu %s @%s \n' % (str(playerid), str(text)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                return _msg
        else:
            return self.Status
    def msgall(self, text):
        """Sends a textmessage to all users on this server instance (no matter on which virtual server they are are hanging out)."""
        if self.xstatus():
            _msg = []
            self.telnet.write('msgall @%s \n' % (str(text)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                return _msg
        else:
            return self.Status
    def fc(self, searchstring):
        """fc will find all channels on the selected virtual server (->sel), that have names containing <searchstring>."""
        if self.xstatus():
            self.telnet.write("fc %s\n" % (str(searchstring)))
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _channels = []
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\d{1,})\s(\d{1,})\s(\S*)\s')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _channel = [int(_filterdata.group(1)), int(_filterdata.group(2)), str(_filterdata.group(3))]
                        _channels.append(_channel)
                return _channels
            else:
                return _msg
        else:
            return self.Status
    def ci(self, channelid):
        """ci will display information on the channel specified with <channelID>."""
        if self.xstatus():
            self.telnet.write("ci %s\n" % (str(channelid)))
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _players = []
                _returndata = []
                _data = re.split("\\n", _data)
                _filterchannelinfo = re.compile(r'(.*?)\s(.*?)\s(.*?)\s"(.*?)"\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s"(.*?)"\s"(.*?)"\s')
                _filterplayer = re.compile(r'(.*?)\s"(.*?)"\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s')
                for _line in _data:
                    _filterdatachannelinfo = _filterchannelinfo.match(_line)
                    _filterdataplayer = _filterplayer.match(_line)
                    if _filterdatachannelinfo != None:
                        _channelinfo = [int(_filterdatachannelinfo.group(1)), int(_filterdatachannelinfo.group(2)), int(_filterdatachannelinfo.group(3)), str(_filterdatachannelinfo.group(4)), int(_filterdatachannelinfo.group(5)), int(_filterdatachannelinfo.group(6)), int(_filterdatachannelinfo.group(7)), int(_filterdatachannelinfo.group(8)), int(_filterdatachannelinfo.group(9)), int(_filterdatachannelinfo.group(10)), int(_filterdatachannelinfo.group(11)), int(_filterdatachannelinfo.group(12)), str(_filterdatachannelinfo.group(13)), str(_filterdatachannelinfo.group(14)), str(_filterdatachannelinfo.group(15)), str(_filterdatachannelinfo.group(16))]
                    elif _filterdataplayer !=None:
                        _player = [int(_filterdataplayer.group(1)), str(_filterdataplayer.group(2)), int(_filterdataplayer.group(3)), int(_filterdataplayer.group(4)), int(_filterdataplayer.group(5)), int(_filterdataplayer.group(6)), int(_filterdataplayer.group(7)), int(_filterdataplayer.group(8)), int(_filterdataplayer.group(9)), int(_filterdataplayer.group(10))]
                        _players.append(_player)
                _returndata.append(_channelinfo)
                _returndata.append(_players)
                return _returndata
            else:
                return _msg
        else:
            return self.Status
    def dbci(self, channelid):
        """This command is used to print the database information about a channel. This includes the rights that are saved in the database, but arent currently used (e.g. rights of users that arent in the channel). Its a useful tool to check on how the rights in your channels are distributed currently."""
        if self.xstatus():
            self.telnet.write("dbci %s\n" % (str(channelid)))
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _players = []
                _returndata = []
                _data = re.split("\\n", _data)
                _filterchannelinfo = re.compile(r'(.*?)\s(.*?)\s"(.*?)"\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s"(.*?)"\s"(.*?)"\s')
                _filterplayer = re.compile(r'(\d{1,})\s(.*?)\s(\d{1,})\s(\d{1,})\s(\d{1,})\s')
                for _line in _data:
                    _filterdatachannelinfo = _filterchannelinfo.match(_line)
                    _filterdataplayer = _filterplayer.match(_line)
                    if _filterdatachannelinfo != None:
                        _channelinfo = [int(_filterdatachannelinfo.group(1)), int(_filterdatachannelinfo.group(2)), str(_filterdatachannelinfo.group(3)), int(_filterdatachannelinfo.group(4)), int(_filterdatachannelinfo.group(5)), int(_filterdatachannelinfo.group(6)), int(_filterdatachannelinfo.group(7)), int(_filterdatachannelinfo.group(8)), int(_filterdatachannelinfo.group(9)), int(_filterdatachannelinfo.group(10)), int(_filterdatachannelinfo.group(11)), str(_filterdatachannelinfo.group(12)), str(_filterdatachannelinfo.group(13)), str(_filterdatachannelinfo.group(14)), str(_filterdatachannelinfo.group(15))]
                    elif _filterdataplayer !=None:
                        _player = [int(_filterdataplayer.group(1)), str(_filterdataplayer.group(2)), int(_filterdataplayer.group(3)), int(_filterdataplayer.group(4)), int(_filterdataplayer.group(5))]
                        _players.append(_player)
                _returndata.append(_channelinfo)
                _returndata.append(_players)
                return _returndata
            elif _msg[1] == 250:
                _returndata = []
                _data = re.split("\\n", _data)
                _filterchannelinfo = re.compile(r'(.*?)\s(.*?)\s"(.*?)"\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s"(.*?)"\s"(.*?)"\s')
                for _line in _data:
                    _filterdatachannelinfo = _filterchannelinfo.match(_line)
                    if _filterdatachannelinfo != None:
                        _channelinfo = [int(_filterdatachannelinfo.group(1)), int(_filterdatachannelinfo.group(2)), str(_filterdatachannelinfo.group(3)), int(_filterdatachannelinfo.group(4)), int(_filterdatachannelinfo.group(5)), int(_filterdatachannelinfo.group(6)), int(_filterdatachannelinfo.group(7)), int(_filterdatachannelinfo.group(8)), int(_filterdatachannelinfo.group(9)), int(_filterdatachannelinfo.group(10)), int(_filterdatachannelinfo.group(11)), str(_filterdatachannelinfo.group(12)), str(_filterdatachannelinfo.group(13)), str(_filterdatachannelinfo.group(14)), str(_filterdatachannelinfo.group(15))]
                _returndata.append(_channelinfo)
                _returndata.append([])
                return _returndata
            else:
                return _msg
        else:
            return self.Status
    def fp(self, searchstring):
        """fp will find all players that have nicks that have <name_substring> in their nick-name or in their login-name."""
        if self.xstatus():
            self.telnet.write("fp %s\n" % (str(searchstring)))
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _players = []
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\d{1,})\s(\d{1,})\s(\d{1,})\s"(.*?)"\s"(.*?)"\s"(.*?)"')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _player = [int(_filterdata.group(1)), int(_filterdata.group(2)), int(_filterdata.group(3)), str(_filterdata.group(4)), str(_filterdata.group(5)), str(_filterdata.group(6))]
                        _players.append(_player)
                return _players
            else:
                return _msg
        else:
            return self.Status
    def dbfp(self, searchstring):
        """ This command will find all the login-accounts that contain the specified string. It will also display their database ID, and if they have SA or not."""
        if self.xstatus():
            self.telnet.write("dbfp %s\n" % (str(searchstring)))
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _players = []
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\d{1,})\s"(.*?)"\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _player = [int(_filterdata.group(1)),str(_filterdata.group(2)),int(_filterdata.group(3)),str(_filterdata.group(4)),str(_filterdata.group(5)),str(_filterdata.group(6)),str(_filterdata.group(7))]
                        _players.append(_player)
                return _players
            else:
                return _msg
        else:
            return self.Status
    def pi(self, playerid):
        """pi will list some information about the player with the <playerID>. It
        contains the ID of the channel he is in, if he is SA, and if he is
        sticky (-> sppriv). It also lists the channel-specific rights this
        player has, and in which channels."""
        if self.xstatus():
            self.telnet.write("pi %s\n" % (str(playerid)))
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _channels = []
                _returndata = []
                _data = re.split("\\n", _data)
                _filterPlayerInfo = re.compile(r'(\d{1,})\s(\d{1,})\s(\d{1,})\s"(.*?)"\s"(.*?)"\s(\d{1,})\s(\d{1,})\s"(.*?)"\s')
                _filterChannelInfo = re.compile(r'(\d{1,})\s"(.*?)"\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s(\d{1,})\s')
                for _line in _data:
                    _filterDataPlayerInfo = _filterPlayerInfo.match(_line)
                    _filterDataChannelInfo = _filterChannelInfo.match(_line)
                    if _filterDataPlayerInfo != None:
                        _player = [int(_filterDataPlayerInfo.group(1)),int(_filterDataPlayerInfo.group(2)),int(_filterDataPlayerInfo.group(3)),str(_filterDataPlayerInfo.group(4)),str(_filterDataPlayerInfo.group(5)),int(_filterDataPlayerInfo.group(6)),int(_filterDataPlayerInfo.group(7)),str(_filterDataPlayerInfo.group(8)),]
                    elif _filterDataChannelInfo != None:
                        _channel = [int(_filterDataChannelInfo.group(1)),str(_filterDataChannelInfo.group(2)),int(_filterDataChannelInfo.group(3)),int(_filterDataChannelInfo.group(4)),int(_filterDataChannelInfo.group(5)),int(_filterDataChannelInfo.group(6)),int(_filterDataChannelInfo.group(7))]
                        _channels.append(_channel)
                _returndata.append(_player)
                _returndata.append(_channels)
                return _returndata
            else:
                return _msg
        else:
            return self.Status
    def dbpi(self, playerid):
        """This command is useful to find out information about users that are
        currently not connected to your server, but that have a registered
        account. As pi (->pi), it will list some information about the player
        specified by the database ID (-> pi) (-> fp) (-> dbuserid). The command will
        also display the last time the account was used, and the time it was made.
        Note: This is a good way of finding out what rights a player has in the
        channels."""
        if self.xstatus():
            self.telnet.write("dbpi %s\n" % (str(playerid)))
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _channels = []
                _player = []
                _returndata = []
                _data = re.split("\\n", _data)
                _filterPlayerInfo = re.compile(r'(\d{1,})\s(.*?)\s(\d{1,})\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s')
                _filterChannelInfo = re.compile(r'(\d{1,})\s(.*?)\s(.*?)\s(\d{1,})\s(\d{1,})\s(\d{1,})\s')
                for _line in _data:
                    _filterDataPlayerInfo = _filterPlayerInfo.match(_line)
                    _filterDataChannelInfo = _filterChannelInfo.match(_line)
                    if _filterDataPlayerInfo != None:
                        _player = [int(_filterDataPlayerInfo.group(1)),str(_filterDataPlayerInfo.group(2)),int(_filterDataPlayerInfo.group(3)),str(_filterDataPlayerInfo.group(4)),str(_filterDataPlayerInfo.group(5)),str(_filterDataPlayerInfo.group(6)),str(_filterDataPlayerInfo.group(7))]
                    elif _filterDataChannelInfo != None:
                        _channel = [int(_filterDataChannelInfo.group(1)),int(_filterDataChannelInfo.group(2)),str(_filterDataChannelInfo.group(3)),int(_filterDataChannelInfo.group(4)),int(_filterDataChannelInfo.group(5)),int(_filterDataChannelInfo.group(6))]
                        _channels.append(_channel)
                _returndata.append(_player)
                _returndata.append(_channels)
                return _returndata
            elif _msg[1] == 250:
                _player = []
                _returndata = []
                _data = re.split("\\n", _data)
                _filterPlayerInfo = re.compile(r'(\d{1,})\s(.*?)\s(\d{1,})\s(.*?)\s(.*?)\s(.*?)\s(.*?)\s')
                for _line in _data:
                    _filterDataPlayerInfo = _filterPlayerInfo.match(_line)
                    if _filterDataPlayerInfo != None:
                        _player = [int(_filterDataPlayerInfo.group(1)),str(_filterDataPlayerInfo.group(2)),int(_filterDataPlayerInfo.group(3)),str(_filterDataPlayerInfo.group(4)),str(_filterDataPlayerInfo.group(5)),str(_filterDataPlayerInfo.group(6)),str(_filterDataPlayerInfo.group(7))]
                _returndata.append(_player)
                return _returndata
            else:
                return _msg
        else:
            return self.Status
    def sppriv(self, playerID, property, value):
        """sppriv will set the property of a player to a new value. The properties
        that are avaliable are:
        property                        possible value
        privilege_serveradmin           1/0
        privilege_canregister           1/0
        privilege_channelsticky         1/0

        channelsticky means this user is not allowed to switch channels
        anymore. He is *glued* to the channel he is in - note that this doesnt
        work on server admins."""
        if self.xstatus():
            self.telnet.write('sppriv %s %s %s \n' % (str(playerID),str(property),str(value)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status 
    def kick(self, playerID, reason):
        """kick will kick the player with the playerID of the server."""
        if self.xstatus():
            self.telnet.write('kick %s %s\n' % (str(playerID),str(reason)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status 
    def removeclient(self, playerID):
        """removeclient will remove a client from the server without the noise of a kick
        - especially usefull for scripting I guess."""
        if self.xstatus():
            self.telnet.write('removeclient %s \n' % (str(playerID)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status 
    def mptc(self, channelID, playerID):
        """ Moves the user with the <playerID> to the channel specified in
        <channelID>. Works like the "drag & drop" functionality of the client,
        so it basicly overrules passwords, userlimits and sticky flags."""
        if self.xstatus():
            self.telnet.write('mptc %s %s \n' % (str(channelID),str(playerID)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def gapl(self, server_port=0):
        """gapl will display the average packet loss of the virtual server that is
        either currently selected (-> sel), or that is specified in <serverport>.
        This value is a good indication to see if something is going wrong on
        the server side (e.g. the bandwidth the server has doesnt suffice).
        On a good server with mostly users from close-by (e.g. European users
        on an European server) the value should be under 1%. If it rises to 5%
        or more you will have major problems using this server to talk."""
        if server_port == 0:
            server_port = self.SelectedServer
        if self.xstatus():
            _averagepacketlos = None
            self.telnet.write('gapl %s \n' % (str(server_port)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filterInfo = re.compile(r'average_packet_loss=(.*?)%\s')
                for _line in _data:
                    _filterDataInfo = _filterInfo.match(_line)
                    if _filterDataInfo != None:
                        _averagepacketloss = _filterDataInfo.group(1)
                return _averagepacketloss
            else:
                return _msg
        else:
            return self.Status
    def log(self, line_amount=30):
        """The log command will print the last 30 lines of server log, if invoked 
        without a parameter, else it will print as many lines as you specify,
        always starting from the end of the log."""
        if self.xstatus():
            self.telnet.write('log %s \n' % (str(line_amount)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                del _data[0]; del _data[len(_data)-1]
                return _data
            else:
                return _msg
        else:
            return self.Status
    def logfind(self, searchstring):
        """Displays all the lines in the serverlog that contain <searchstring>, making it
        easy to find things in the log if you know what you are looking for."""
        if self.xstatus():
            self.telnet.write('logfind %s \n' % (str(searchstring)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                del _data[0]; del _data[len(_data)-1]
                return _data
            else:
                return _msg
        else:
            return self.Status
    def logmark(self, string):
        """This is used to set a remark in the serverlog. It is useful if you
        want to find a specific place in the log file later. For example if
        you notice a problem and want to look at the log closer some time to
        find out what was up."""
        if self.xstatus():
            self.telnet.write('logmark %s \n' % (str(string)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dccl(self):
        """After you selected a virtual Server (-> sel), the dccl command prints
        out a list of all clients, sorted by the channels they are in. The first
        column displays the Channel ID, the second the Channel Name, the third
        the Player ID and the fourth the Player Name. If a Channel is empty, the
        Player ID will be -1."""
        if self.xstatus():
            self.telnet.write("dccl \n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _clients = []
                _data = re.split("\\n", _data)
                _filterChannelwithPlayer = re.compile(r'(\d{1,})\s"(.*?)"\s(\d{1,})\s"(.*?)"\s')
                _filterChannelwithoutPlayer = re.compile(r'(\d{1,})\s"(.*?)"\s(.*?)\s')
                for _line in _data:
                    _filterDataChannelwithPlayer = _filterChannelwithPlayer.match(_line)
                    _filterDataChannelwithoutPlayer = _filterChannelwithoutPlayer.match(_line)
                    if _filterDataChannelwithPlayer != None:
                        _client = [int(_filterDataChannelwithPlayer.group(1)),str(_filterDataChannelwithPlayer.group(2)),int(_filterDataChannelwithPlayer.group(3)),str(_filterDataChannelwithPlayer.group(4))]
                        _clients.append(_client)
                    elif _filterDataChannelwithoutPlayer != None:
                        _client = [int(_filterDataChannelwithoutPlayer.group(1)),str(_filterDataChannelwithoutPlayer.group(2)),int(_filterDataChannelwithoutPlayer.group(3))]
                        _clients.append(_client)
                return _clients
            else:
                return _msg
        else:
            return self.Status
    def serverstart(self, server_database_id):
        """serverstart will start the, previously stopped (-> dbserverstop) virtual
        server specified by <server_database_id>. To obtain a such an ID, list
        the servers in the database (-> dbserverlist)."""
        if self.xstatus():
            self.telnet.write('serverstart %s \n' % (str(server_database_id)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def serverstop(self):
        """serverstop will stop the selected virtual server
        (-> sel). To be able to use the server again, you have to start it
        (-> serverstart)."""
        if self.xstatus():
            self.telnet.write('serverstop \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def serveradd(self, port):
        """serveradd will add a new virtual server to run on <port>. You can
        configure it either with tcpquery (-> serverset), or via webadmin interface."""
        if self.xstatus():
            self.telnet.write('serveradd %s \n' % (str(port)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def serverdel(self, server_database_id):
        """serverdel will delete the virtual server specified by
        <server_database_ID>."""
        if self.xstatus():
            self.telnet.write('serverdel %s \n' % (str(server_database_id)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def serverset(self, attribute, value):
        """serverset will change the <attribute> of the selected virtual server
        (-> sel) to <value>. There are various attributes avaliable to be set,
        among them are possibilities to modify clanserver vs publicserver, allow
        or disallow different voice codecs, set maximum users, server password,
        server name, welcome message and the post and link url, which are both
        needed for webpost.
        Now lets have a look at the names of the attibutes, and their possible
        values:

        attribute                               value

        server_clan_server                      0/1
        server_allow_codec_windowscelp52        0/1
        server_allow_codec_gsm164               0/1
        server_allow_codec_gsm148               0/1
        server_allow_codec_celp63               0/1
        server_allow_codec_celp51               0/1
        server_allow_codec_speex2150            0/1
        server_allow_codec_speex3950            0/1
        server_allow_codec_speex5950            0/1
        server_allow_codec_speex8000            0/1
        server_allow_codec_speex11000           0/1
        server_allow_codec_speex15000           0/1
        server_allow_codec_speex18200           0/1
        server_allow_codec_speex24600           0/1
        server_maxusers                         0-32000
        server_password                         text
        server_name                             text
        server_welcomemessage                   text
        server_webpost_posturl                  text
        server_webpost_linkurl                  text"""
        if self.xstatus():
            self.telnet.write('serverset %s %s\n' % (str(attribute), str(value)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dbserverlist(self):
        """dbserverlist will print a list of all virtual servers
        running on this server instance. It will print their database ID, the
        port they run on, their name and finaly if they are running or not."""
        if self.xstatus():
            self.telnet.write('dbserverlist \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _dbserverlist = []
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filterdbserverlist = re.compile(r'(\d{1,})\s(\d{1,})\s"(.*?)"\s(\d{1,})')
                for _line in _data:
                    _filterDatadbserverlist = _filterdbserverlist.match(_line)
                    if _filterDatadbserverlist != None:
                        _dbserver = [int(_filterDatadbserverlist.group(1)),int(_filterDatadbserverlist.group(2)),str(_filterDatadbserverlist.group(3)),int(_filterDatadbserverlist.group(4))]
                        _dbserverlist.append(_dbserver)
                return _dbserverlist
            else:
                return _msg
        else:
            return self.Status
    def checkserverok(self):
        """checkserverok will return "OK" if the server is running
        fine, else "error" if this server isnt working properly anymore, has
        *hung*."""
        if self.xstatus():
            self.telnet.write('checkserverok \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def rehash(self):
        """This will reload the entries in the database - possibly useful if you
        have written a tool that manipulates the server database, then it might
        be sensible to rehash the database in order for the server to *notice*
        the changes."""
        if self.xstatus():
            self.telnet.write('rehash \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dbuserlist(self):
        """After selecting a virtual server (-> sel) this command
        will print a whole list of all registered users, sorted by the DBUserID.
        The first column is the DBUserID, the second one is the SAStatus
        (0 means user is no SA, -1 means user is SA). The third column tells
        you when the user registered with the server, the forth tells you when
        the most recent login with this account occured and the fifth and last
        one is the LoginName."""
        if self.xstatus():
            self.telnet.write('dbuserlist \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _dbuserlist = []
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filterdbuserlist = re.compile(r'(\d{1,})\s(.*?)\s(\d{1,}-\d{1,}-\d{1,})\s(\d{1,}:\d{1,}:\d{1,})\s(\d{1,}-\d{1,}-\d{1,})\s(\d{1,}:\d{1,}:\d{1,})\s"(.*?)"\s')
                _filterdbuserlistwithoutlogin = re.compile(r'(\d{1,})\s(.*?)\s(\d{1,}-\d{1,}-\d{1,})\s(\d{1,}:\d{1,}:\d{1,})\s(\S*)\s"(.*?)"\s')
                for _line in _data:
                    _filterDatadbuserlist = _filterdbuserlist.match(_line)
                    _filterDatadbuserlistwithoutlogin = _filterdbuserlistwithoutlogin.match(_line)
                    if _filterDatadbuserlist != None:
                        _dbuser = [int(_filterDatadbuserlist.group(1)),int(_filterDatadbuserlist.group(2)),str(_filterDatadbuserlist.group(3)),str(_filterDatadbuserlist.group(4)),str(_filterDatadbuserlist.group(5)),str(_filterDatadbuserlist.group(6)),str(_filterDatadbuserlist.group(7))]
                        _dbuserlist.append(_dbuser)
                    if _filterDatadbuserlistwithoutlogin != None:
                        _dbuser = [int(_filterDatadbuserlistwithoutlogin.group(1)),int(_filterDatadbuserlistwithoutlogin.group(2)),str(_filterDatadbuserlistwithoutlogin.group(3)),str(_filterDatadbuserlistwithoutlogin.group(4)),str(_filterDatadbuserlistwithoutlogin.group(5)),str(_filterDatadbuserlistwithoutlogin.group(6))]
                        _dbuserlist.append(_dbuser)
                return _dbuserlist
            else:
                return _msg
        else:
            return self.Status
    def dbuseradd(self, LoginName, Password, ServerAdminStatus):
        """After selecting a virtual server (-> sel) you can use this command
        to add a registered useraccount to your selected server's database.
        To make sure you typed in the password correctly it's entered twice.
        The "ServerAdminStatus" is 1 or 0, 1: user is SA, 0: user isn't."""
        if self.xstatus():
            self.telnet.write('dbuseradd %s %s %s %s \n' % (str(LoginName),str(Password),str(Password),str(ServerAdminStatus)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dbuserdel(self, DBUserID):
        """After you selected a virtual server (-> sel) you can delete registered
        users out of your database with this command. To get the DBUserID use
        the dbuserlist (-> dbuserlist) or dbuserid (-> dbuserid) command."""
        if self.xstatus():
            self.telnet.write('dbuserdel %s \n' % (str(DBUserID)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dbuserchangepw(self, DBUserID, Password):
        """After selecting a virtual server (-> sel) you can use this command
        to change a registered user's password. To get the DBUserID use
        dbuserlist (-> dbuserlist) or dbuserid (-> dbuserid). The new pass-
        word is entered twice to ensure correct writing."""
        if self.xstatus():
            self.telnet.write('dbuserchangepw %s %s %s \n' % (str(DBUserID),str(Password),str(Password)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dbuserid(self, LoginName):
        """After selecting a virtual server (-> sel) you can use this command
        to change a registered user's password. To get the DBUserID use
        dbuserlist (-> dbuserlist) or dbuserid (-> dbuserid). The new pass-
        word is entered twice to ensure correct writing."""
        if self.xstatus():
            self.telnet.write('dbuserid %s \n' % (str(LoginName)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filterID = re.compile(r'(\d{1,})\s')
                for _line in _data:
                    _filterDataID = _filterID.match(_line)
                    if _filterDataID != None:
                        _id = _filterDataID.group(1)
                return _id
            else:
                return _msg
        else:
            return self.Status
    def dbsuserlist(self):
        """This command will print a whole list of all registered
        users, sorted by the DBSUserID.
        The first column is the DBSUserID, the second one is the date when
        the SuperAdmin was registered, the third is the time of the last login (this is
        either a webadmin or a tcpquery login) and the forth and last one is the
        LoginName."""
        if self.xstatus():
            self.telnet.write('dbsuserlist \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _dbuserlist = []
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filterdbuserlist = re.compile(r'(\d{1,})\s(\d{1,}-\d{1,}-\d{1,})\s(\d{1,}:\d{1,}:\d{1,})\s(\d{1,}-\d{1,}-\d{1,})\s(\d{1,}:\d{1,}:\d{1,})\s"(.*?)"\s')
                _filterdbuserlistwithoutlogin = re.compile(r'(\d{1,})\s(\d{1,}-\d{1,}-\d{1,})\s(\d{1,}:\d{1,}:\d{1,})\s(\S*)\s"(.*?)"\s')
                for _line in _data:
                    _filterDatadbuserlist = _filterdbuserlist.match(_line)
                    _filterDatadbuserlistwithoutlogin = _filterdbuserlistwithoutlogin.match(_line)
                    if _filterDatadbuserlist != None:
                        _dbuser = [int(_filterDatadbuserlist.group(1)),str(_filterDatadbuserlist.group(2)),str(_filterDatadbuserlist.group(3)),str(_filterDatadbuserlist.group(4)),str(_filterDatadbuserlist.group(5)),str(_filterDatadbuserlist.group(6))]
                        _dbuserlist.append(_dbuser)
                    if _filterDatadbuserlistwithoutlogin != None:
                        _dbuser = [int(_filterDatadbuserlistwithoutlogin.group(1)),str(_filterDatadbuserlistwithoutlogin.group(2)),str(_filterDatadbuserlistwithoutlogin.group(3)),str(_filterDatadbuserlistwithoutlogin.group(4)),str(_filterDatadbuserlistwithoutlogin.group(5))]
                        _dbuserlist.append(_dbuser)
                return _dbuserlist
            else:
                return _msg
        else:
            return self.Status
    def dbsuseradd(self, LoginName, Password):
        """You can use the dbsuseradd command to add a new SuperAdmin to your
        server instance. To make sure you typed in the password correctly
        it's entered twice."""
        if self.xstatus():
            self.telnet.write('dbsuseradd %s %s %s \n' % (str(LoginName),str(Password),str(Password)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dbsuserdel(self, DBSUserID):
        """With this command you can delete SuperAdmin accounts.
        To get the DBSUserID use the dbsuserlist (-> dbsuserlist) command."""
        if self.xstatus():
            self.telnet.write('dbsuserdel %s \n' % (str(DBSUserID)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def dbsuserchangepw(self, DBSUserID, Password):
        """You can use this command to change a SuperAdmin's password. To get
        the DBSUserID use dbsuserlist (-> dbsuserlist). The new password is
        entered twice to ensure correct writing."""
        if self.xstatus():
            self.telnet.write('dbsuserchangepw %s %s %s \n' % (str(DBSUserID),str(Password),str(Password)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def lc(self):
        """lc will return a lists current connections with the
        tcpquery-port, so that you can see other Admins / SuperAdmins who are
        logged in with telnet. Notice that only SSAs can execute this command."""
        if self.xstatus():
            self.telnet.write('lc \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            _telnetusers = []
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filterTelnetUser = re.compile(r'"(.*?)"\s(\d{1,})\s(\d{1,})\s(\d{1,})\s"(\d{1,}.\d{1,}.\d{1,}.\d{1,})"\s"(.*?)"\s')
                for _line in _data:
                    _filterDataTelnetUser = _filterTelnetUser.match(_line)
                    if _filterDataTelnetUser != None:
                        _telnetuser = [str(_filterDataTelnetUser.group(1)),int(_filterDataTelnetUser.group(2)),int(_filterDataTelnetUser.group(3)),int(_filterDataTelnetUser.group(4)),str(_filterDataTelnetUser.group(5)),str(_filterDataTelnetUser.group(6))]
                        _telnetusers.append(_telnetuser)
                return _telnetusers
            else:
                return _msg
        else:
            return self.Status
    def ki(self, IdleTime, Target, Reason):
        """After selecting a virtual server (-> sel) you can use this command
        to kick people who are idle for "IdleTime" minutes.
        "Target" is a parameter that specifies who gets kicked. Sum up:
         1: unregistered clients
         2: registered clients
         4: kick only if client is on unregistered channel
         8: kick only if client is on registered channel
        "Reason" is the reason for the kick that every kicked player will get.
        After executing this command the server will return a number of all
        players kicked."""
        if self.xstatus():
            _kicked = None
            self.telnet.write('ki %s %s %s \n' % (str(IdleTime),str(Target),str(Reason)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _data = re.split("\\n", _data)
                _filterInfo = re.compile(r'kicked=(.*?)\s')
                for _line in _data:
                    _filterDataInfo = _filterInfo.match(_line)
                    if _filterDataInfo != None:
                        _kicked = _filterDataInfo.group(1)
                return _kicked
            else:
                return _msg
        else:
            return self.Status
    def banlist(self):
        """This will print out all bans that are currently
        enforced on the selected server. It will also display you with lots of
        useful information about these bans.
        Lets look what the colums mean:
        b_id    the ban ID, usefull for bandel for example
        ip      the IP (with possible wildcards) that is banned
        created the time this ban was created
        mins    if this is a timeban, howlong it was created for, else its zero
        by      information about who set the ban."""
        if self.xstatus():
            self.telnet.write("banlist \n")
            _data = self.telnet.read_until("OK", self.Timeout)
            _msg = self.xerror(_data)
            if _msg[1] == 100:
                _players = []
                _data = re.split("\\n", _data)
                _filter = re.compile(r'(\d{1,})\s(\d{1,}.\d{1,}.\d{1,}.\d{1,})\s(\d{1,}-\d{1,}-\d{1,})\s(\d{1,}:\d{1,}:\d{1,})\s(\d{1,})\s"(.*?)"\s')
                for _line in _data:
                    _filterdata = _filter.match(_line)
                    if _filterdata != None:
                        _player = [int(_filterdata.group(1)), str(_filterdata.group(2)), str(_filterdata.group(3)), str(_filterdata.group(4)), int(_filterdata.group(5)), str(_filterdata.group(6))]
                        _players.append(_player)
                return _players
            else:
                return _msg
        else:
            return self.Status
    def banadd(self, ip, time):
        """This will put the IP you specified on the banlist of the currently
        selected server. Also note that the IP may contain wildcards, just like
        known from the client banlist. So, you could use the wildcard "*" to ban
        more than only one guy, or to ban whole netmasks/providers.
        You can also specify a time after the IP, measured in minutes, which
        will make your ban become a "time ban", meaning it will only last for as
        long as you specified."""
        if self.xstatus():
            self.telnet.write('banadd %s %s \n' % (str(ip),str(time)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def bandel(self, ban_id):
        """This will delete the ban specified by ban_id (->banlist) out of the
        banlist of the selected server."""
        if self.xstatus():
            self.telnet.write('bandel %s\n' % (str(ban_id)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def banclear(self):
        """Is used to delete all bans that your banlist contains,
        maybe useful if you gave the wrong guy Admin and want to clean-up your
        messed up banlist."""
        if self.xstatus():
            self.telnet.write('banclear \n')
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def banplayer(self, playerid, time):
        """This is handy if you dont want to look up the IP of somebody connected
        to your server, but just want to ban him. The IP of player corresponding
        to the ID is banned. Note: This is ban only, no kick occurs.
        banplayer can also be used to place "time bans", that is bans that only
        last for a certain amount of time. The option <time> is measured in
        minutes."""
        if self.xstatus():
            self.telnet.write('banplayer %s %s \n' % (str(playerid),str(time)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status
    def globalset(self, attribute, value):
        """globalset will change the <attribute> of the teamspeak instance and
        set it to <value>.
        These are the currently available attributes and their values:

        attribute                               value
        hoster_gfx_url                          text
                Note: This is a URL to a image to be displayed to connected
                clients, changes to it will only be visible to clients
                connecting after you changed it - and the changes will not be
                saved to the server.ini, meaning will not be permanent over a
                server restart.
        allowedclientnamechars                  text
                Note: This restricts what characters you will allow in
                nicknames. Users with disallowed characters will get a message
                when they connect.
        disallowedclientnamechars               text
                Note: This is the little brother of allowedclientnamechars -
                characters you set here will not be allowed in nicknames,
                clients will be informed what characters they are using that
                are not allowed on this server. The default setting for this
                will be "()[]{}" to prevent flag faking."""
        if self.xstatus():
            self.telnet.write('globalset %s %s\n' % (str(attribute), str(value)))
            _data = self.telnet.read_until('OK', self.Timeout)
            _msg = self.xerror(_data)
            return _msg
        else:
            return self.Status

class LogParser():
    def __init__(self):
        self.source = None
        self.FilterAccessLogConnected = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\sSID:\s(\d+)\s(client\sconnected)\s\[IP:\s(\d+.\d+.\d+.\d+),\sNick:\s(.*?),\sVersion:\s(\d+.\d+.\d+.\d+)\]\s')
        self.FilterAccessLogDisconnected = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\sSID:\s(\d+)\s(client\sdisconnected.)\s\[Nick:\s(.*?)\]\s')
        self.FilterAccessLogBan = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\sSID:\s(\d+)\s(client\sdisconnected,\sreason\sClient\sis\sbanned)\s\[IP:\s(\d+.\d+.\d+.\d+),\sNick:\s(.*?),\sLoginName:\s(.*?),\sVersion:\s(\d+.\d+.\d+.\d+)\]')
        self.FilterSALogTCPQuery = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\s(tcpquery)\s:\s(superserveradmin\sconnected)\s\[IP:\s(\d+.\d+.\d+.\d+),\sLoginName:\s(.*?)\]')
        self.FilterSALogWeb = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\s(web)\s:\s(superserveradmin\sconnected)\s\[IP:\s(\d+.\d+.\d+.\d+),\sLoginName:\s(.*?)\]')
        self.FilterSALogWebServerAdmin = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\s(web)\s:\s(serveradmin\sconnected)\s\[IP:\s(\d+.\d+.\d+.\d+),\sLoginName:\s(.*?),\sServerPort:\s(\d+)\]')
        self.FilterChannelLog = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\sSID:\s(\d+)\s([^\r\n\f]+)\s\[ChannelName:\s(.*?),\sClientNickName:\s(.*?),\sClientLoginName:\s(.*?)\]')
        self.FilterServerKickLog = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\sSID:\s(\d+)\s\[PlayerName:\s(.*?),\sLoginName:\s(.*?),\sDBID:\s(.*?)\]\sgot\skicked\sfrom\sserver\sby\s\[PlayerName:\s(.*?),\sLoginName:\s(.*?),\sDBID:\s(.*?)\], reason:\s(.*?)\s')
        self.FilterServerIniti = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\s(Server\s[^\r\n\f]+\s[^\r\n\f]+)')
        self.FilterServerStart = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\s([^\r\n\f]+ VirtualServer)\sid:(\d+) with port:(\d+)')
        self.FilterLog = re.compile(r'[-]+\s([^\r\n\f]+)\sat\s(\d+-\d+-\d+)\s(\d+:\d+)\s[-]+')
        self.FilterMark = re.compile(r'(\d+-\d+-\d+)\s(\d+:\d+:\d+),(\w+),(\w+),(\w+),\s\*([^\r\n\f]+)\sby\s([^\r\n\f]+)\*\s([^\r\n\f]+)')
    def parse(self, source):
        self.source = source
        self.FilterdSource = []
        for line in self.source:
            FilterAccessLogConnectedDATA = self.FilterAccessLogConnected.match(line)
            FilterAccessLogDisconnectedDATA = self.FilterAccessLogDisconnected.match(line)
            FilterAccessLogBanDATA = self.FilterAccessLogBan.match(line)
            FilterSALogTCPQueryDATA = self.FilterSALogTCPQuery.match(line)
            FilterSALogWebDATA = self.FilterSALogWeb.match(line)
            FilterSALogWebServerAdminDATA = self.FilterSALogWebServerAdmin.match(line)
            FilterChannelLogDATA = self.FilterChannelLog.match(line)
            FilterServerKickLogDATA = self.FilterServerKickLog.match(line)
            FilterServerInitiDATA = self.FilterServerIniti.match(line)
            FilterServerStartDATA = self.FilterServerStart.match(line)
            FilterLogDATA = self.FilterLog.match(line)
            FilterMarkDATA = self.FilterMark.match(line)
            if FilterAccessLogConnectedDATA != None:
                LineFilterd = [str(FilterAccessLogConnectedDATA.group(1)),str(FilterAccessLogConnectedDATA.group(2)),str(FilterAccessLogConnectedDATA.group(3)),str(FilterAccessLogConnectedDATA.group(4)),str(FilterAccessLogConnectedDATA.group(5)),int(FilterAccessLogConnectedDATA.group(6)),str(FilterAccessLogConnectedDATA.group(7)),str(FilterAccessLogConnectedDATA.group(8)),str(FilterAccessLogConnectedDATA.group(9)),str(FilterAccessLogConnectedDATA.group(10))]
                self.FilterdSource.append(LineFilterd)
            elif FilterAccessLogDisconnectedDATA != None:
                LineFilterd = [str(FilterAccessLogDisconnectedDATA.group(1)),str(FilterAccessLogDisconnectedDATA.group(2)),str(FilterAccessLogDisconnectedDATA.group(3)),str(FilterAccessLogDisconnectedDATA.group(4)),str(FilterAccessLogDisconnectedDATA.group(5)),int(FilterAccessLogDisconnectedDATA.group(6)),str(FilterAccessLogDisconnectedDATA.group(7)),str(FilterAccessLogDisconnectedDATA.group(8))]
                self.FilterdSource.append(LineFilterd)
            elif FilterAccessLogBanDATA != None:
                LineFilterd = [str(FilterAccessLogBanDATA.group(1)),str(FilterAccessLogBanDATA.group(2)),str(FilterAccessLogBanDATA.group(3)),str(FilterAccessLogBanDATA.group(4)),str(FilterAccessLogBanDATA.group(5)),int(FilterAccessLogBanDATA.group(6)),str(FilterAccessLogBanDATA.group(7)),str(FilterAccessLogBanDATA.group(8)),str(FilterAccessLogBanDATA.group(9)),str(FilterAccessLogBanDATA.group(10)),str(FilterAccessLogBanDATA.group(11))]
                self.FilterdSource.append(LineFilterd)
            elif FilterSALogTCPQueryDATA != None:
                LineFilterd = [str(FilterSALogTCPQueryDATA.group(1)),str(FilterSALogTCPQueryDATA.group(2)),str(FilterSALogTCPQueryDATA.group(3)),str(FilterSALogTCPQueryDATA.group(4)),str(FilterSALogTCPQueryDATA.group(5)),str(FilterSALogTCPQueryDATA.group(6)),str(FilterSALogTCPQueryDATA.group(7)),str(FilterSALogTCPQueryDATA.group(8)),str(FilterSALogTCPQueryDATA.group(9))]
                self.FilterdSource.append(LineFilterd)
            elif FilterSALogWebDATA != None:
                LineFilterd = [str(FilterSALogWebDATA.group(1)),str(FilterSALogWebDATA.group(2)),str(FilterSALogWebDATA.group(3)),str(FilterSALogWebDATA.group(4)),str(FilterSALogWebDATA.group(5)),str(FilterSALogWebDATA.group(6)),str(FilterSALogWebDATA.group(7)),str(FilterSALogWebDATA.group(8))]
                self.FilterdSource.append(LineFilterd)
            elif FilterSALogWebServerAdminDATA != None:
                LineFilterd = [str(FilterSALogWebServerAdminDATA.group(1)),str(FilterSALogWebServerAdminDATA.group(2)),str(FilterSALogWebServerAdminDATA.group(3)),str(FilterSALogWebServerAdminDATA.group(4)),str(FilterSALogWebServerAdminDATA.group(5)),str(FilterSALogWebServerAdminDATA.group(6)),str(FilterSALogWebServerAdminDATA.group(7)),str(FilterSALogWebServerAdminDATA.group(8)),str(FilterSALogWebServerAdminDATA.group(9)),int(FilterSALogWebServerAdminDATA.group(10))]
                self.FilterdSource.append(LineFilterd)
            elif FilterChannelLogDATA != None:
                LineFilterd = [str(FilterChannelLogDATA.group(1)),str(FilterChannelLogDATA.group(2)),str(FilterChannelLogDATA.group(3)),str(FilterChannelLogDATA.group(4)),str(FilterChannelLogDATA.group(5)),int(FilterChannelLogDATA.group(6)),str(FilterChannelLogDATA.group(7)),str(FilterChannelLogDATA.group(8)),str(FilterChannelLogDATA.group(9)),str(FilterChannelLogDATA.group(10))]
                self.FilterdSource.append(LineFilterd)
            elif FilterServerKickLogDATA != None:
                LineFilterd = [str(FilterServerKickLogDATA.group(1)),str(FilterServerKickLogDATA.group(2)),str(FilterServerKickLogDATA.group(3)),str(FilterServerKickLogDATA.group(4)),str(FilterServerKickLogDATA.group(5)),int(FilterServerKickLogDATA.group(6)),str(FilterServerKickLogDATA.group(7)),str(FilterServerKickLogDATA.group(8)),str(FilterServerKickLogDATA.group(9)),str(FilterServerKickLogDATA.group(10)),str(FilterServerKickLogDATA.group(11)),int(FilterServerKickLogDATA.group(12)),str(FilterServerKickLogDATA.group(13))]
                self.FilterdSource.append(LineFilterd)
            elif FilterServerInitiDATA != None:
                LineFilterd = [str(FilterServerInitiDATA.group(1)),str(FilterServerInitiDATA.group(2)),str(FilterServerInitiDATA.group(3)),str(FilterServerInitiDATA.group(4)),str(FilterServerInitiDATA.group(5)),str(FilterServerInitiDATA.group(6))]
                self.FilterdSource.append(LineFilterd)
            elif FilterServerStartDATA != None:
                LineFilterd = [str(FilterServerStartDATA.group(1)),str(FilterServerStartDATA.group(2)),str(FilterServerStartDATA.group(3)),str(FilterServerStartDATA.group(4)),str(FilterServerStartDATA.group(5)),str(FilterServerStartDATA.group(6)),int(FilterServerStartDATA.group(7)),int(FilterServerStartDATA.group(8))]
                self.FilterdSource.append(LineFilterd)
            elif FilterLogDATA != None:
                LineFilterd = [str(FilterLogDATA.group(1)),str(FilterLogDATA.group(2)),str(FilterLogDATA.group(3))]
                self.FilterdSource.append(LineFilterd)
            elif FilterMarkDATA != None:
                LineFilterd = [str(FilterMarkDATA.group(1)),str(FilterMarkDATA.group(2)),str(FilterMarkDATA.group(3)),str(FilterMarkDATA.group(4)),str(FilterMarkDATA.group(5)),str(FilterMarkDATA.group(6)),str(FilterMarkDATA.group(7)),str(FilterMarkDATA.group(8))]
                self.FilterdSource.append(LineFilterd)
        return self.FilterdSource